#include "core/common.h"

class ChatClient {
private:
    int clientSocket;
    std::string username;
    std::string serverIP;
    int serverPort;
    std::atomic<bool> running;
    std::atomic<bool> connected;

public:
    ChatClient(const std::string& ip = "127.0.0.1", int port = DEFAULT_PORT) 
        : serverIP(ip), serverPort(port), running(false), connected(false) {}
    
    ~ChatClient() {
        disconnect();
    }
    
    bool connect() {
        // 创建socket
        clientSocket = socket(AF_INET, SOCK_STREAM, 0);
        if (clientSocket < 0) {
            std::cerr << "ERROR: Failed to create socket" << std::endl;
            return false;
        }
        
        // 设置服务器地址
        sockaddr_in serverAddr;
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_port = htons(serverPort);
        
        if (inet_pton(AF_INET, serverIP.c_str(), &serverAddr.sin_addr) <= 0) {
            std::cerr << "ERROR: Invalid server IP address" << std::endl;
            return false;
        }
        
        // 连接服务器
        if (::connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
            std::cerr << "ERROR: Failed to connect to server " << serverIP << ":" << serverPort << std::endl;
            return false;
        }
        
        connected = true;
        std::cout << "Connected to server " << serverIP << ":" << serverPort << std::endl;
        return true;
    }
    
    void disconnect() {
        if (connected) {
            // 发送登出消息
            Message logoutMsg(MSG_LOGOUT, username, "");
            sendMessage(logoutMsg);
            
            connected = false;
            running = false;
            
            if (clientSocket >= 0) {
                close(clientSocket);
            }
            
            std::cout << "Disconnected from server" << std::endl;
        }
    }
    
    bool login(const std::string& user) {
        if (!connected) {
            std::cerr << "ERROR: Not connected to server" << std::endl;
            return false;
        }
        
        username = user;
        Message loginMsg(MSG_LOGIN, username, "");
        sendMessage(loginMsg);
        
        // 等待服务器响应
        char buffer[BUFFER_SIZE];
        memset(buffer, 0, BUFFER_SIZE);
        int bytesReceived = recv(clientSocket, buffer, BUFFER_SIZE - 1, 0);
        
        if (bytesReceived > 0) {
            std::string data(buffer);
            Message response = Message::deserialize(data);
            
            if (response.type == MSG_LOGIN) {
                std::cout << "Login successful! Welcome " << username << "!" << std::endl;
                return true;
            } else if (response.type == MSG_ERROR) {
                std::cout << "Login failed: " << response.content << std::endl;
                return false;
            }
        }
        
        std::cout << "Login failed: No response from server" << std::endl;
        return false;
    }
    
    void run() {
        if (!connected) {
            std::cerr << "ERROR: Not connected to server" << std::endl;
            return;
        }
        
        running = true;
        
        // 启动消息接收线程
        std::thread receiveThread(&ChatClient::receiveMessages, this);
        
        // 主线程处理用户输入
        handleUserInput();
        
        // 等待接收线程结束
        if (receiveThread.joinable()) {
            receiveThread.join();
        }
    }
    
private:
    void sendMessage(const Message& msg) {
        if (connected) {
            std::string data = msg.serialize();
            send(clientSocket, data.c_str(), data.length(), 0);
        }
    }
    
    void receiveMessages() {
        char buffer[BUFFER_SIZE];
        
        while (running && connected) {
            memset(buffer, 0, BUFFER_SIZE);
            int bytesReceived = recv(clientSocket, buffer, BUFFER_SIZE - 1, 0);
            
            if (bytesReceived <= 0) {
                if (running) {
                    std::cout << "\nConnection lost with server" << std::endl;
                }
                break;
            }
            
            std::string data(buffer);
            Message msg = Message::deserialize(data);
            
            switch (msg.type) {
                case MSG_CHAT:
                    if (msg.username == "Server") {
                        std::cout << "\n[System] " << msg.content << std::endl;
                    } else {
                        std::cout << "\n[" << msg.username << "] " << msg.content << std::endl;
                    }
                    std::cout << "Enter message (or '/help' for commands): ";
                    std::cout.flush();
                    break;
                    
                case MSG_USER_LIST:
                    std::cout << "\n" << msg.content << std::endl;
                    std::cout << "Enter message (or '/help' for commands): ";
                    std::cout.flush();
                    break;
                    
                case MSG_ERROR:
                    std::cout << "\nError: " << msg.content << std::endl;
                    std::cout << "Enter message (or '/help' for commands): ";
                    std::cout.flush();
                    break;
                    
                default:
                    break;
            }
        }
        
        connected = false;
        running = false;
    }
    
    void handleUserInput() {
        std::string input;
        
        std::cout << "\n=== Chat Client ===" << std::endl;
        std::cout << "Commands:" << std::endl;
        std::cout << "  /help    - Show this help" << std::endl;
        std::cout << "  /users   - Show online users" << std::endl;
        std::cout << "  /quit    - Exit the chat" << std::endl;
        std::cout << "===================" << std::endl;
        
        while (running && connected) {
            std::cout << "Enter message (or '/help' for commands): ";
            std::getline(std::cin, input);
            
            if (std::cin.eof() || !running || !connected) {
                break;
            }
            
            if (input.empty()) {
                continue;
            }
            
            // 处理命令
            if (input[0] == '/') {
                if (input == "/help") {
                    showHelp();
                } else if (input == "/users") {
                    Message userListMsg(MSG_USER_LIST, username, "");
                    sendMessage(userListMsg);
                } else if (input == "/quit") {
                    std::cout << "Goodbye!" << std::endl;
                    break;
                } else {
                    std::cout << "Unknown command. Type '/help' for available commands." << std::endl;
                }
            } else {
                // 发送聊天消息
                Message chatMsg(MSG_CHAT, username, input);
                sendMessage(chatMsg);
            }
        }
        
        running = false;
    }
    
    void showHelp() {
        std::cout << "\n=== Available Commands ===" << std::endl;
        std::cout << "  /help    - Show this help message" << std::endl;
        std::cout << "  /users   - Show list of online users" << std::endl;
        std::cout << "  /quit    - Exit the chat" << std::endl;
        std::cout << "=========================" << std::endl;
        std::cout << "Simply type your message and press Enter to chat!" << std::endl;
    }
};

int main(int argc, char* argv[]) {
    std::string serverIP = "127.0.0.1";
    int port = DEFAULT_PORT;
    std::string username;
    
    // 解析命令行参数
    if (argc > 1) {
        serverIP = argv[1];
    }
    if (argc > 2) {
        port = std::atoi(argv[2]);
        if (port <= 0 || port > 65535) {
            std::cerr << "Invalid port number. Using default port " << DEFAULT_PORT << std::endl;
            port = DEFAULT_PORT;
        }
    }
    
    std::cout << "=== IM Chat Client ===" << std::endl;
    std::cout << "Server: " << serverIP << ":" << port << std::endl;
    
    // 获取用户名
    std::cout << "Enter your username: ";
    std::getline(std::cin, username);
    
    if (username.empty()) {
        std::cerr << "Username cannot be empty" << std::endl;
        return 1;
    }
    
    // 创建客户端并连接
    ChatClient client(serverIP, port);
    
    if (!client.connect()) {
        return 1;
    }
    
    // 登录
    if (!client.login(username)) {
        return 1;
    }
    
    // 设置信号处理
    signal(SIGINT, [](int) {
        std::cout << "\nDisconnecting..." << std::endl;
        exit(0);
    });
    
    // 运行客户端
    client.run();
    
    return 0;
} 